package com.hopes.bizz.risk.job;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.common.core.annotation.TenantJobRun;
import com.hopes.bizz.common.core.util.DateUtils;
import com.hopes.bizz.risk.common.constant.MessageGroupEnum;
import com.hopes.bizz.risk.common.constant.RiskDicConstant;
import com.hopes.bizz.risk.control.entity.RiskMeasureTaskEntity;
import com.hopes.bizz.risk.control.entity.RiskMeasureTaskRecordEntity;
import com.hopes.bizz.risk.control.service.RiskMeasureTaskRecordService;
import com.hopes.bizz.risk.control.service.RiskMeasureTaskService;
import com.hopes.bizz.risk.setting.entity.RiskCalendarEntity;
import com.hopes.bizz.risk.setting.service.RiskCalendarService;
import com.hopes.bizz.risk.support.RiskCheckTaskGenSupport;
import com.hopes.bizz.risk.sys.bo.SysMessageEvent;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/7/21 14:24
 * @Description: 风险隐患检查生成任务
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RiskHiddenCheckGenerateService {

    private final RiskCalendarService sysCalendarService;
    private final RiskMeasureTaskService riskMeasureTaskService;
    private final RiskCheckTaskGenSupport riskCheckTaskGenSupport;
    private final RiskMeasureTaskRecordService riskMeasureTaskRecordService;
    private final ApplicationEventPublisher eventPublisher;

    @TenantJobRun
    @Transactional(rollbackFor = Exception.class)
    @XxlJob("riskHiddenCheckGenerateJobHandler")
    public void riskHiddenCheckGenerateJobHandler() {

        final Calendar calendar = Calendar.getInstance();
        final Date date = DateUtils.dateLimitDay(calendar.getTime());
        final RiskCalendarEntity sysCalendar = sysCalendarService.getOne(date);
        Assert.notNull(sysCalendar, "时间：" + DateUtils.limitDay(date) + " 数据对象获取异常！");
        Assert.notNull(sysCalendar.getDateType(), "时间：" + DateUtils.limitDay(date) + " 日期类型获取异常！");


        /* 1、查询所有开始的任务 */
        LambdaQueryWrapper<RiskMeasureTaskEntity> measureTaskWrapper = Wrappers.lambdaQuery();
        measureTaskWrapper.eq(RiskMeasureTaskEntity::getTaskStatus, RiskDicConstant.HIDDEN_CHECK_CONFIG_STATUS_USE);
        measureTaskWrapper.isNull(RiskMeasureTaskEntity::getLatestCheckDate).or().le(RiskMeasureTaskEntity::getLatestCheckDate, calendar.getTime());
        final List<RiskMeasureTaskEntity> riskMeasureTaskList = riskMeasureTaskService.list(measureTaskWrapper);

        /* 2、根据排查周期类型分类 */
         final Map<String, List<RiskMeasureTaskEntity>> listMap = riskMeasureTaskList.stream().filter(e ->
                ObjectUtil.isNotNull(e.getCheckCycleType())).collect(Collectors.groupingBy(RiskMeasureTaskEntity::getCheckCycleType));
        if (MapUtil.isEmpty(listMap)) {
            return;
        }

        String nowDayStr = DateUtils.formatDate(calendar.getTime(), DateUtils.FORMAT_DAY);

        /* 3、处理 年 周期的任务 */
        final List<RiskMeasureTaskEntity> yearTaskList = listMap.get(RiskDicConstant.RISK_CHECK_CYCLE_TYPE_YEAR);
        final List<RiskMeasureTaskRecordEntity> hiddenCheckTaskList = riskCheckTaskGenSupport.handlerYearAndMonthCycleTask(calendar, Calendar.YEAR, nowDayStr, yearTaskList);

        /* 4、处理 月 周期的任务 */
        final List<RiskMeasureTaskEntity> monthTaskList = listMap.get(RiskDicConstant.RISK_CHECK_CYCLE_TYPE_MONTH);
        final List<RiskMeasureTaskRecordEntity> monthRecordList = riskCheckTaskGenSupport.handlerYearAndMonthCycleTask(calendar, Calendar.MONTH, nowDayStr, monthTaskList);

        /* 5、处理 天 周期的任务 */
        final List<RiskMeasureTaskEntity> dayTaskList = listMap.get(RiskDicConstant.RISK_CHECK_CYCLE_TYPE_DAY);
        final List<RiskMeasureTaskRecordEntity> dayRecordList = riskCheckTaskGenSupport.handlerDayAndHourCycleTask(calendar, Calendar.DAY_OF_MONTH, nowDayStr, sysCalendar, dayTaskList);

        /* 6、处理 小时 周期的任务 */
        final List<RiskMeasureTaskEntity> hourTaskList = listMap.get(RiskDicConstant.RISK_CHECK_CYCLE_TYPE_HOUR);
        final List<RiskMeasureTaskRecordEntity> hourRecordList = riskCheckTaskGenSupport.handlerDayAndHourCycleTask(calendar, Calendar.HOUR_OF_DAY, nowDayStr, sysCalendar, hourTaskList);

        hiddenCheckTaskList.addAll(monthRecordList);
        hiddenCheckTaskList.addAll(dayRecordList);
        hiddenCheckTaskList.addAll(hourRecordList);
        log.debug("保存的记录数量：{}, {}, {}, {}", hiddenCheckTaskList.size(), monthRecordList, dayRecordList, hourRecordList);
        riskMeasureTaskRecordService.saveBatch(hiddenCheckTaskList);

        // 推送消息
        for (RiskMeasureTaskRecordEntity riskPointHiddenCheckTask : hiddenCheckTaskList) {
            SysMessageEvent sysMessageBo = new SysMessageEvent();
            sysMessageBo.setUserIdList(Collections.singletonList(riskPointHiddenCheckTask.getTaskHandleUserId()));
            sysMessageBo.setBusiness(riskPointHiddenCheckTask.getId());
            sysMessageBo.setMessageContent(riskPointHiddenCheckTask.getCheckContent());
            sysMessageBo.setMessageGroupEnum(MessageGroupEnum.risk_hidden_check);
            eventPublisher.publishEvent(sysMessageBo);
        }
    }
}

